/**
 * 
 */
package dt.inlee.common.dao.impl;

import java.io.Serializable;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.Query;
import org.hibernate.Session;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.orm.hibernate3.HibernateTemplate;

import dt.inlee.common.exception.FrameworkException;
import dt.inlee.common.util.BaseUtil;
import dt.inlee.common.util.HqlUtil;

/**
 * @功能说明：
 * @作者： THINK
 * @创建日期： 2011-6-5
 */
@SuppressWarnings("rawtypes")
public abstract class BaseDao {

	protected static Log log = LogFactory.getLog(BaseDao.class);
	@Resource(name = "hibernateTemplate")
	protected HibernateTemplate hibernateTemplate;
	@Resource(name = "jdbcTemplate")
	protected JdbcTemplate jdbcTemplate;

	/********************************************************************************************************************************
	 *                                                                                                                              * 
	 *                                                   基本操作(增、删、改、查)--START                                              *
	 *                                                                                                                              *
	 ********************************************************************************************************************************/
	/**
	 * 保存持久化实体
	 * 
	 * @param entity
	 *		-实体对象
	 * @return Serializable
	 * @throws FrameworkException
	 */
	public Serializable save(Object entity) throws FrameworkException {
		return hibernateTemplate.save(entity);
	}

	/**
	 * 修改持久化实体
	 * 
	 * @param entity
	 *		-实体对象
	 * @throws FrameworkException
	 */

	public void update(Object entity) throws FrameworkException {
		hibernateTemplate.update(entity);
	}

	/**
	 * 修改持久化实体
	 * 
	 * 调用save(entity)方法之前调用的方法，主要解决OneToMany级联保存或修改
	 * a different object with the same identifier value was already associated with the session
	 * 
	 * @param entity
	 *      -实体对象
	 * @return object
	 * @throws FrameworkException
	 */
	public Object merge(Object entity) throws FrameworkException {
		return hibernateTemplate.merge(entity);
	}

	/**
	 * 删除指定持久化实例
	 * 
	 * @param entity
	 *		-实体对象
	 * @throws FrameworkException
	 */
	public void delete(Object entity) throws FrameworkException {
		hibernateTemplate.delete(entity);
	}

	/**
	 * 删除集合内全部持久化实体
	 * 
	 * @param entitys
	 *		-持久化集合实体
	 * @throws FrameworkException
	 */
	public void deleteAll(Collection entitys) throws FrameworkException {
		hibernateTemplate.deleteAll(entitys);
	}

	/**
	 * 删除指定持久化实体
	 * @param cls
	 *      -class类型
	 * @param id
	 *		-持久化实体ID
	 * @throws FrameworkException
	 */
	public void deleteById(Class cls, Serializable id) throws FrameworkException {
		this.delete(this.get(cls, id));
	}

	/**
	 * 获取单个持久化实体
	 * @param cls
	 *      -class类型
	 * @param id
	 * @return object
	 * @throws FrameworkException
	 */
	@SuppressWarnings("unchecked")
    public Object get(Class cls, Serializable id) throws FrameworkException {
		return hibernateTemplate.get(cls, id);

	}

	/**
	 * 无条件获取所有实体
	 * @param cls
	 *      -class类型
	 * @return list
	 * @throws FrameworkException
	 */
	public List findAll(Class cls) throws FrameworkException {
		return hibernateTemplate.find("FROM " + cls.getSimpleName());
	}

	/********************************************************************************************************************************
	 *                                                                                                                              * 
	 *                                                   基本操作(增、删、改、查)--END                                              *
	 *                                                                                                                              *
	 ********************************************************************************************************************************/

	/********************************************************************************************************************************
	 *                                                                                                                              * 
	 *                                                   列表分页显示--START                                                         *
	 *                                                                                                                              *
	 ********************************************************************************************************************************/
	/**
	 * 获取满足条件的多个实体
	 * @param cls
	 *      -class类型
	 * @param hql
	 *		-标准hql语句
	 * @param condition
	 *		-查询条件
	 * @return List
	 * @throws FrameworkException
	 */
	public List findAllEntitiesByCondition(final Class cls, final String hql, final Map<String, Object> condition)
			throws FrameworkException {
		return this.findAllEntitiesByCondition(cls, hql, condition, -1, -1);
	}

	/**
	 * 获取满足条件的多个实体
	 * @param cls
	 *      -class类型
	 * @param condition
	 *		-查询条件
	 * @return List
	 * @throws FrameworkException
	 */
	public List findAllEntitiesByCondition(final Class cls, final Map<String, Object> condition)
			throws FrameworkException {
		return this.findAllEntitiesByCondition(cls, null, condition, -1, -1);
	}

	/**
	 * 获取满足条件的多个实体
	 * @param hql
	 *		-标准hql
	 * @param condition
	 *		-查询条件
	 * @return List
	 * @throws FrameworkException
	 */
	public List findAllEntitiesByCondition(final String hql, final Map<String, Object> condition)
			throws FrameworkException {
		return this.findAllEntitiesByCondition(null, hql, condition, -1, -1);
	}

	/**
	 * 根据动态条件查询满足条件的实体
	 * @param cls
	 *      -class类型
	 * @param condition
	 *		-查询条件
	 * @param currentPage
	 *		-当前页数
	 * @param pageSize
	 *		-每页值的大小
	 * @return List
	 * @throws FrameworkException
	 */
	public List findAllEntitiesByCondition(final Class cls, final Map<String, Object> condition, final int currentPage,
			final int pageSize) throws FrameworkException {
		return this.findAllEntitiesByCondition(cls, null, condition, currentPage, pageSize);

	}

	/**
	 * 根据动态条件查询满足条件的实体
	 * @param hql
	 *		-标准hql
	 * @param condition
	 *		-查询条件
	 * @param currentPage
	 *		-当前页数
	 * @param pageSize
	 *		-每页值的大小
	 * @return List
	 * @throws FrameworkException
	 */

    public List findAllEntitiesByCondition(final String hql, final Map<String, Object> condition,
			final int currentPage, final int pageSize) throws FrameworkException {
		return this.findAllEntitiesByCondition(null, hql, condition, currentPage, pageSize);

	}

	/**
	 * 根据动态条件查询满足条件的实体
	 * @param cls
	 *      -class类型
	 * @param hql
	 * 		-标准hql
	 * @param condition
	 *		-查询条件
	 * @param currentPage
	 *		-当前页数
	 * @param pageSize
	 *		-每页值的大小
	 * @return List
	 * @throws FrameworkException
	 */
	public List findAllEntitiesByCondition(final Class cls, final String hql, final Map<String, Object> condition,
			final int currentPage, final int pageSize) throws FrameworkException {
		Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
		Query query = null;
		Map<String, Object> tempCondition = condition;
		String tempHql = hql;
		if (!BaseUtil.isEmpty(tempCondition) && !condition.isEmpty()) {
			Set<String> keys = tempCondition.keySet();
			if (BaseUtil.isEmpty(tempHql)) {
				Map<String, Map<String, Object>> securityHqlCondition = HqlUtil.generateSecurityHql(tempCondition);
				String whereCondition = securityHqlCondition.keySet().iterator().next();
				tempHql = "FROM " + cls.getSimpleName() + whereCondition;
				tempCondition = securityHqlCondition.get(whereCondition);
				keys = tempCondition.keySet();
			}
			query = session.createQuery(tempHql);
			for (String key : keys) {
				query.setParameter(key, tempCondition.get(key));
			}

		} else {
			if (BaseUtil.isEmpty(tempHql))
				tempHql = "FROM " + cls.getSimpleName();
			query = session.createQuery(tempHql);
		}
		if (currentPage > 0 && pageSize > 0) {
			query.setFirstResult((currentPage - 1) * pageSize);
			query.setMaxResults(pageSize);
		}
		List list = query.list();
		return list;

	}

	/**
	 * 根据动态条件查询满足条件的实体记录总数
	 * @param hql
	 *		-标准hql
	 * @param condition
	 *		-查询条件
	 * @return int
	 * @throws FrameworkException
	 */
	public int getTotalRows(final String hql, final Map<String, Object> condition) throws FrameworkException {
		return this.getTotalRows(null, hql, condition);
	}

	/**
	 * 根据动态条件查询满足条件的实体记录总数
	 * @param cls
	 *      -class类型
	 * @param condition
	 *		-查询条件
	 * @return int
	 * @throws FrameworkException
	 */
	public int getTotalRows(final Class cls, final Map<String, Object> condition) throws FrameworkException {
		return this.getTotalRows(cls, null, condition);
	}

	/**
	 * 根据动态条件查询满足条件的实体记录总数
	 * 
	 * @param hql
	 *		-标准hql
	 * @param cls
	 *      -class类型
	 * @param condition
	 *		-查询条件
	 * @return int
	 * @throws FrameworkException
	 */
	public int getTotalRows(final Class cls, final String hql, final Map<String, Object> condition)
			throws FrameworkException {
		Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
		Query query = null;
		Map<String, Object> tempCondition = condition;
		String tempHql = hql;
		if (!BaseUtil.isEmpty(tempCondition) && !condition.isEmpty()) {
			Set<String> keys = tempCondition.keySet();
			if (BaseUtil.isEmpty(tempHql)) {
				Map<String, Map<String, Object>> securityHqlCondition = HqlUtil.generateSecurityHql(tempCondition);
				String whereCondition = securityHqlCondition.keySet().iterator().next();
				tempHql = "SELECT COUNT(*) FROM " + cls.getSimpleName() + whereCondition;
				tempCondition = securityHqlCondition.get(whereCondition);
				keys = tempCondition.keySet();
			}
			query = session.createQuery(tempHql);
			for (String key : keys) {
				query.setParameter(key, tempCondition.get(key));
			}
		} else {
			if (BaseUtil.isEmpty(tempHql))
				tempHql = "SELECT COUNT(*) FROM " + cls.getSimpleName();
			query = session.createQuery(tempHql);
		}
		Object obj = query.list().get(0);
		return ((Long) obj).intValue();
	}

	/**
	 * 根据动态条件查询满足条件的单值
	 * 
	 * @param hql
	 *		-标准hql
	 * @param condition
	 *		-查询条件
	 * @return int
	 * @throws FrameworkException
	 */
	public String getSimpleValue(final String hql, final Map<String, Object> condition) throws FrameworkException {
		Session session = hibernateTemplate.getSessionFactory().getCurrentSession();
		Query query = null;
		Map<String, Object> tempCondition = condition;
		String tempHql = hql;
		if (!BaseUtil.isEmpty(tempCondition) && !condition.isEmpty()) {
			Set<String> keys = tempCondition.keySet();
			query = session.createQuery(tempHql);
			for (String key : keys) {
				query.setParameter(key, tempCondition.get(key));
			}
		} else {
			query = session.createQuery(tempHql);
		}
		Object obj = query.list().get(0);
		return (String) obj;

	}

	/********************************************************************************************************************************
	 *                                                                                                                              * 
	 *                                                   列表分页显示--END                                                           *
	 *                                                                                                                              *
	 ********************************************************************************************************************************/

	/********************************************************************************************************************************
	 *                                                                                                                              * 
	 *                                                   批量更新--START                                                             *
	 *                                                                                                                              *
	 ********************************************************************************************************************************/
	/**
	 * 批量更新(HQL版本,不涉及任何其他更新数据和条件数据)
	 * @param hql
	 *    - hql语句
	 * @return boolean
	 * @throws FrameworkException
	 */
	public boolean batchUpdate(String hql) throws FrameworkException {
		return this.batchUpdate(hql, null, null);

	}

	/**
	 * 批量更新(HQL版本,只涉及条件数据)
	 * @param hql
	 *    - hql语句
	 * @param condition
	 *    -查询条件
	 * @return  boolean
	 * @throws FrameworkException
	 */
	public boolean batchUpdate(Map<String, Object> condition, String hql) throws FrameworkException {
		return this.batchUpdate(hql, null, condition);
	}

	/**
	 * 批量更新(HQL版本,只涉及数据包括更新数据)
	 * @param hql
	 *    - hql语句
	 * @param updateData
	 *    -更新数据
	 * @return boolean
	 * @throws FrameworkException
	 */
	public boolean batchUpdate(String hql, Map<String, Object> updateData) throws FrameworkException {
		return this.batchUpdate(hql, updateData, null);
	}

	/**
	 * 批量更新(HQL版本,涉及数据包括更新数据和条件数据)
	 * @param hql
	 *    - hql语句
	 * @param updateData
	 *    -更新数据
	 * @param whereCondition
	 *    -更新条件
	 * @return boolean
	 * @throws FrameworkException
	 */
	public boolean batchUpdate(String hql, Map<String, Object> updateData, Map<String, Object> condition)
			throws FrameworkException {
		if (!BaseUtil.isEmpty(condition) && !condition.isEmpty() && !BaseUtil.isEmpty(updateData)
				&& !updateData.isEmpty()) {
			Set<String> whereKeys = condition.keySet();
			Map<String, Map<String, Object>> securityHqlCondition = HqlUtil.generateSecurityHql(condition);
			String whereCondition = securityHqlCondition.keySet().iterator().next();
			String tempHql = hql + whereCondition;
			Query query = hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(tempHql);
			Map<String, Object> tempCondition = securityHqlCondition.get(whereCondition);
			whereKeys = tempCondition.keySet();
			for (String key : whereKeys) {
				query.setParameter(key, tempCondition.get(key));
			}
			Set<String> updateKeys = updateData.keySet();
			for (String key : updateKeys) {
				query.setParameter(key, updateData.get(key));
			}
			if (query.executeUpdate() > 0)
				return true;
			return false;
		} else if (!BaseUtil.isEmpty(condition) && !condition.isEmpty()
				&& (BaseUtil.isEmpty(updateData) || updateData.isEmpty())) {
			Set<String> whereKeys = condition.keySet();
			Map<String, Map<String, Object>> securityHqlCondition = HqlUtil.generateSecurityHql(condition);
			String whereCondition = securityHqlCondition.keySet().iterator().next();
			String tempHql = hql + whereCondition;
			Query query = hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(tempHql);
			Map<String, Object> tempCondition = securityHqlCondition.get(whereCondition);
			whereKeys = tempCondition.keySet();
			for (String key : whereKeys) {
				query.setParameter(key, tempCondition.get(key));
			}
			if (query.executeUpdate() > 0)
				return true;
			return false;
		} else if ((BaseUtil.isEmpty(condition) || condition.isEmpty()) && !BaseUtil.isEmpty(updateData)
				&& !updateData.isEmpty()) {
			Query query = hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(hql);
			Set<String> updateKeys = updateData.keySet();
			for (String key : updateKeys) {
				query.setParameter(key, updateData.get(key));
			}
			if (query.executeUpdate() > 0)
				return true;
			return false;
		} else {
			Query query = hibernateTemplate.getSessionFactory().getCurrentSession().createQuery(hql);
			if (query.executeUpdate() > 0)
				return true;
			return false;
		}
	}
	/********************************************************************************************************************************
	 *                                                                                                                              * 
	 *                                                   批量更新--END                                                               *
	 *                                                                                                                              *
	 ********************************************************************************************************************************/
}
